﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace Seven.Tools.Extension
{
    /// <summary>
    /// 枚举扩展方法类
    /// </summary>
    public static class EnumExtensions
    {
        /// <summary>
        /// 获取枚举项的Description特性的描述文字
        /// </summary>
        /// <param name="enumeration"> </param>
        /// <returns> </returns>
        public static string ToDescription(this Enum enumeration)
        {
            Type type = enumeration.GetType();
            MemberInfo[] members = type.GetMember(enumeration.CastTo<string>());
            if (members.Length > 0)
            {
                return members[0].ToDescription();
            }
            return enumeration.CastTo<string>();
        }

        /// <summary>
        /// 获取枚举值的字段显示名称。
        /// </summary>
        /// <param name="_this">枚举值。</param>
        /// <returns>枚举值的字段显示名称。</returns>
        public static string DisplayName(this System.Enum _this)
        {
            return System.Enum.GetName(_this.GetType(), _this);
        }

        /// <summary>
        /// 获取该枚举值字段所定义的所有指定类型的自定义特性的数组。
        /// </summary>
        /// <typeparam name="TResult">指定的自定义特性类型。</typeparam>
        /// <param name="_this">要获取自定义特性的枚举值。</param>
        /// <returns>该枚举值字段所定义的所有指定类型的自定义特性的数组。</returns>
        public static IEnumerable<TResult> GetCustomeAttributes<TResult>(this System.Enum _this) where TResult : Attribute
        {
            return _this.GetType().GetField(_this.DisplayName()).GetCustomAttributes<TResult>(true);
        }

        /// <summary>
        /// 获取该枚举值字段所定义的所有指定类型的自定义特性的数组。
        /// </summary>
        /// <param name="_this">要获取自定义特性的枚举值。</param>
        /// <param name="attributeType">指定的自定义特性类型。</param>
        /// <returns>该枚举值字段所定义的所有指定类型的自定义特性的数组。</returns>
        public static IEnumerable<Attribute> GetCustomeAttributes(this System.Enum _this, System.Type attributeType)
        {
            Check.NotNull(attributeType);
            return _this.GetType().GetField(_this.DisplayName()).GetCustomAttributes(attributeType, true).OfType<Attribute>();
        }
    }
}
